package com.xhwl.data.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import com.xhwl.common.dto.cent.sdata.*;
import com.xhwl.common.enums.LogOperationTypeEnum;
import com.xhwl.common.enums.ModuleTypeEnum;
import com.xhwl.common.enums.OrganizationTypeEnum;
import com.xhwl.common.enums.config.BusinessType;
import com.xhwl.common.enums.config.RoleTypeEnum;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.exception.DataException;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.*;
import com.xhwl.common.query.cent.sdata.OrganizationQuery;
import com.xhwl.common.query.cent.sdata.ProjectQuery;
import com.xhwl.common.query.cent.sdata.RoleQuery;
import com.xhwl.common.utils.ThreadLocalUtil;
import com.xhwl.data.dao.*;
import com.xhwl.data.service.*;
import com.xhwl.data.util.AutoCodeUtils;
import com.xhwl.data.util.CodePrefixConstant;
import com.xhwl.data.util.ValidatorUtil;
import com.xhwl.starter.log.LogTemplate;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @description: 项目管理
 * @author: lianghz
 * @create: 2020-11-25
 **/
@Service
public class ProjectServiceImpl extends ServiceImpl<IProjectDao, Project> implements IProjectService {

    @Autowired
    private IProjectPermissionService projectPermissionService;

    @Autowired
    private IOrganizationDao organizationDao;

    @Autowired
    private IPermissionService permissionService;

    @Autowired
    private IRoleService roleService;
    @Autowired
    private IRolePermissionService rolePermissionService;

    @Autowired
    private IProjectDao projectDao;

    @Autowired
    private IAccountOrganizationDao accountOrganizationDao;

    @Autowired
    private IAccountProjectDao accountProjectDao;

    @Autowired
    private IProjectPermissionDao projectPermissionDao;

    @Autowired
    private IOrganizationService organizationService;

    @Autowired
    private IPermissionDao permissionDao;

    @Autowired
    private IRoleDao roleDao;

    @Autowired
    private IRolePermissionDao rolePermissionDao;

    @Autowired
    private IProjectAppService projectAppService;


    @Autowired
    LogTemplate logTemplate;

    @Autowired
    private IAccountService accountService;

    @Autowired
    private IPermissionGroupService permissionGroupService;

    @Autowired
    private IRegionService regionService;

    @Autowired
    private IEnterpriseDao enterpriseDao;

    @Autowired
    private IEnterpriseProjectDao enterpriseProjectDao;

    @Autowired
    private IEnterpriseService enterpriseService;

    @Autowired
    private IIndustryService industryService;

    @Autowired
    private ISceneService sceneService;

    @Autowired
    private IProjectExtraService projectExtraService;

    private static final Logger log = LoggerFactory.getLogger(ProjectServiceImpl.class);

    private static final List<String> EXCLUDE_PROJECT_PERMISSION = Arrays.asList("enterpriseAdd", "enterpriseModify", "enterpriseDetail", "projectAdd", "projectModify");

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson create(ProjectDTO projectDTO, Account account) {

        ResultJson resultJson1 = paramCheck(projectDTO);
        if (!resultJson1.getState()) {
            return resultJson1;
        }

        Project project = new Project();
        BeanUtils.copyProperties(projectDTO, project);
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();

        if(null != account){
            List<Integer> enterpriseIds = accountService.getEnterpriseIds(account.getId());
            organizationQueryWrapper.in("enterprise_id", enterpriseIds);
        }

        if (null != projectDTO.getParentOrgId()) {
            organizationQueryWrapper.eq("id", projectDTO.getParentOrgId());
        } else {
            organizationQueryWrapper.eq("enterprise_id", projectDTO.getEnterpriseId());
            organizationQueryWrapper.eq("type", OrganizationTypeEnum.ENTERPRISE.id);
        }
        Organization parent = organizationDao.selectOne(organizationQueryWrapper);
        if (null == parent) {
            throw new DataException("上级不存在");
        }
        /**
         * 防止项目层级套项目
         */
        if (parent.getType() == OrganizationTypeEnum.PROJECT.id.intValue()) {
            return ResultJson.fail("上级数据错误");
        }
        project.setEnterpriseId(parent.getEnterpriseId());
        this.saveCheck(project);
        Organization organization = new Organization();
        organization.setName(project.getName());
        organization.setIndustryId(parent.getIndustryId());
        organization.setEnterpriseId(projectDTO.getEnterpriseId());
        organization.setLevel(parent.getLevel() + 1);
        organization.setParentId(parent.getId());
        organization.setIsDeleted(false);
        organization.setType(OrganizationTypeEnum.PROJECT.id.intValue());
        ResultJson resultJson = organizationService.create(organization);
        if (!resultJson.getState()) {
            return resultJson;
        }
        project.setOrganizationId(organization.getId());
        // 更新组织id
        projectDao.insert(project);
        if (StringUtils.isEmpty(project.getCode())) {
            String code = AutoCodeUtils.codeFormat(CodePrefixConstant.PROJECT_PREFIX, project.getId(), CodePrefixConstant.CODE_LENGTH);
            project.setCode(code);
            projectDao.updateById(project);
        }
        organization.setProjectId(project.getId());
        organization.setCode(project.getCode());
        organizationDao.updateById(organization);

        List<Integer> buttonPermissionIdList = permissionService.findButtonIdByMenuId(projectDTO.getPermissions());
        if (!CollectionUtils.isEmpty(buttonPermissionIdList)) {
            projectDTO.getPermissions().addAll(buttonPermissionIdList);
        }
        savePermissions(project.getId(), projectDTO.getPermissions());
        //记录拓展信息
        projectExtraService.save(JSONObject.toJSONString(projectDTO.getExtraInfo()), project.getId());

        // 创建与app的关联关系
        createProjectApp(projectDTO.getPermissions(), project);
        // 绑定运营商企管
        bindProject(projectDTO.getEnterpriseId(),Arrays.asList(project.getId()),false);
        //运营商授权
        saveEntProject(projectDTO.getEnterpriseId(),project.getId());
        //记录日志
        projectLogRecord(account, LogOperationTypeEnum.CREATE, "新增项目" + "【" + project.getName() + "】", project);
        return ResultJson.success("创建成功", project.getId());
    }
    /**
     * 企管绑定项目
     */
    @Override
    public void bindProject(Integer enterpriseId,List<Integer> projectIds,Boolean flag){
        Account manager = getManager(enterpriseId);
        if(manager == null || CollectionUtils.isEmpty(projectIds)){
            return;
        }
        //sdata_account_project
        for(Integer projectId:projectIds) {
            QueryWrapper<AccountProject> accountProjectQueryWrapper = new QueryWrapper<>();
            accountProjectQueryWrapper.eq("account_id", manager.getId());
            accountProjectQueryWrapper.eq("project_id",projectId);
            List<AccountProject> accountProjects = accountProjectDao.selectList(accountProjectQueryWrapper);
            if(CollectionUtils.isEmpty(accountProjects)) {
                AccountProject accountProject = new AccountProject();
                accountProject.setProjectId(projectId);
                accountProject.setAccountId(manager.getId());
                accountProjectDao.insert(accountProject);
            }
        }
        //sdata_permission_group
        QueryWrapper<PermissionGroup> permissionGroupQueryWrapper = new QueryWrapper<>();
        permissionGroupQueryWrapper.eq("account_id", manager.getId());
        permissionGroupQueryWrapper.eq("enterprise_id",enterpriseId);
        permissionGroupQueryWrapper.orderByAsc("created_at");
        List<PermissionGroup> list = permissionGroupService.list(permissionGroupQueryWrapper);
        if(CollectionUtils.isEmpty(list)){
            return;
        }
        //遍历权限组
        PermissionGroup vo = list.get(0);
        String projectStr = null;
        //是否覆盖
        if(flag){
            projectStr=Joiner.on(",").join(projectIds);
        }else {
            String projectIdStr = vo.getProjectIds();
            if(StringUtils.isEmpty(projectIdStr)){
                projectStr = Joiner.on(",").join(projectIds);
            }else{
                List<Integer> result = new ArrayList<>(projectIds);
                String[] split = projectIdStr.split(",");
                for (String s : split) {
                    result.add(Integer.parseInt(s));
                }
                //去重
                projectStr=Joiner.on(",").join(result.stream().distinct().collect(Collectors.toList()));
            }
        }
        vo.setProjectIds(projectStr);
        permissionGroupService.updateById(vo);
    }


    /**
     * 获得企业管理员账号
     * @param enterpriseId
     * @return
     */
    private Account getManager(Integer enterpriseId) {
        if (enterpriseId == null) {
            return null;
        }
        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.in("enterprise_id", enterpriseId);
        roleQueryWrapper.eq("type", RoleTypeEnum.MANAGER.code);
        roleQueryWrapper.eq("is_initialized", true);
        roleQueryWrapper.eq("is_deleted", false);
        List<Role> list = roleService.list(roleQueryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            // 查询企业管理员帐号
            Map<Integer, List<Account>> roleAccountMap = accountService.getByRoleIds(list.stream().map(i -> i.getId()).collect(Collectors.toList()));
            for (Map.Entry<Integer, List<Account>> integerListEntry : roleAccountMap.entrySet()) {
                List<Account> value = integerListEntry.getValue();
                if (org.springframework.util.CollectionUtils.isEmpty(value)) {
                    continue;
                }
                Account account = value.get(0);
                if(null == account) {
                    continue;
                }
                return account;
            }
        }
        return null;
    }

    private void saveEntProject(Integer enterpriseId, Integer id) {
        QueryWrapper<EnterpriseProject> enterpriseProjectQueryWrapper = new QueryWrapper<>();
        enterpriseProjectQueryWrapper.eq("enterprise_id", enterpriseId);
        enterpriseProjectDao.delete(enterpriseProjectQueryWrapper);
        EnterpriseProject enterpriseProject = new EnterpriseProject();
        enterpriseProject.setEnterpriseId(enterpriseId);
        enterpriseProject.setProjectId(id);
        enterpriseProjectDao.insert(enterpriseProject);
    }

    /**
     * 创建项目管理员账号
     *
     * @param
     * @param accountDTO
     * @param roleId
     * @param projectId
     * @param enterpriseId
     * @return
     */
    private ResultJson createMangerAccount(AccountDTO accountDTO, Integer roleId, Integer projectId, Integer enterpriseId) {
        Account account = new Account();
        BeanUtils.copyProperties(accountDTO, account);
        if (StringUtils.isEmpty(account.getLoginName())) {
            account.setLoginName(UUID.randomUUID().toString().replaceAll("-", ""));
        }
        return accountService.createAccount(account, Arrays.asList(enterpriseId), Arrays.asList(projectId), Arrays.asList(roleId));
    }

    private void createProjectApp(List<Integer> permissionIds, Project project) {
        QueryWrapper<Permission> permissionQueryWrapper = new QueryWrapper<>();
        permissionQueryWrapper.in("id", permissionIds);
        permissionQueryWrapper.eq("is_deleted", false);
        permissionQueryWrapper.select("id", "app_id");
        List<Permission> permissions = permissionDao.selectList(permissionQueryWrapper);

        Set<Integer> collect1 = permissions.stream().map(i -> i.getAppId()).collect(Collectors.toSet());
        List<ProjectApp> projectApps = new ArrayList<>(collect1.size());
        for (Integer i : collect1) {
            ProjectApp projectApp = new ProjectApp();
            projectApp.setAppId(i);
            projectApp.setProjectId(project.getId());
            projectApps.add(projectApp);
        }
        projectAppService.saveBatch(projectApps);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Integer id, Account account) {
        if (null == account) {
            log.info("当前删除项目的账号信息为空");
        } else {
            log.info("帐号 {} 删除项目 {}", account.getId(), id);
        }

        Project project = getById(id);
        if(null == project){
            throw new DataException("项目不存在");
        }
        project.setIsDeleted(true);
        projectDao.updateById(project);
        organizationDao.deleteById(project.getOrganizationId());
        // 删除关联关系
        this.deleteRelation(id);
        // 删除与app的关联关系
        QueryWrapper<ProjectApp> projectAppQueryWrapper = new QueryWrapper<>();
        projectAppQueryWrapper.eq("project_id", id);
        projectAppService.remove(projectAppQueryWrapper);
        //记录日志
        projectLogRecord(account, LogOperationTypeEnum.DELETE, "删除项目" + "【" + project.getName() + "】", project);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson update(ProjectDTO projectDTO, Account account) {

        ResultJson resultJson = paramCheck(projectDTO);
        if (!resultJson.getState()) {
            return resultJson;
        }
        Project project = new Project();
        BeanUtils.copyProperties(projectDTO, project);

        Project projectOld = this.getOne(new ProjectQuery(projectDTO.getId()), account);
        if(null == projectOld){
            throw new DataException("项目不存在");
        }
        project.setEnterpriseId(projectOld.getEnterpriseId());
        this.saveCheck(project);
        projectDao.updateById(project);

        Organization org = organizationService.getById(projectOld.getOrganizationId());
        org.setName(project.getName());
        org.setCode(project.getCode());
        ResultJson update = organizationService.update(org);
        if (!update.getState()) {
            return update;
        }
        // 保存权限关系，包含按钮权限的集合
        List<Integer> permissions = this.savePermissions(project.getId(), projectDTO.getPermissions());
        // 修改项目下所有角色的权限
        // 管理员的
        List<Role> managerRoles = this.queryManagerRoleId(project.getId());
        if (!managerRoles.isEmpty()) {
            // 修改管理角色 (先删除后新增)
            for (Role role : managerRoles) {
                rolePermissionService.createRolePermission(role.getId(), permissions);
            }
        }
        // 普通角色的 （只需要删除即可）
        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.eq("project_id", project.getId());
        roleQueryWrapper.eq("grade", 0);
        roleQueryWrapper.ne("type", RoleTypeEnum.MANAGER);
        roleQueryWrapper.ne("is_deleted", false);
        List<Role> roles = roleDao.selectList(roleQueryWrapper);
        if (!roles.isEmpty()) {
            QueryWrapper<ProjectPermission> projectPermissionQueryWrapper = new QueryWrapper<>();
            projectPermissionQueryWrapper.eq("project_id", project.getId());
            List<ProjectPermission> permissionList = projectPermissionDao.selectList(projectPermissionQueryWrapper);
            if (!permissionList.isEmpty()) {
                List<Integer> permissionId = permissionList.stream().map(p -> p.getPermissionId()).collect(Collectors.toList());
                List<Integer> deletes = new ArrayList<>();
                deletes.addAll(permissionId);
                permissionId.retainAll(projectDTO.getPermissions());
                deletes.removeAll(permissionId);
                if (!deletes.isEmpty()) {
                    QueryWrapper<RolePermission> rolePermissionQueryWrapper = new QueryWrapper<>();
                    rolePermissionQueryWrapper.in("permission_id", deletes);
                    rolePermissionDao.delete(rolePermissionQueryWrapper);
                }
            }
        }
        //记录拓展信息
        projectExtraService.save(JSONObject.toJSONString(projectDTO.getExtraInfo()), project.getId());
        //运营商授权
        saveEntProject(projectDTO.getEnterpriseId(),project.getId());
        // 创建与app的关联关系
        QueryWrapper<ProjectApp> projectAppQueryWrapper = new QueryWrapper<>();
        projectAppQueryWrapper.eq("project_id", project.getId());
        projectAppService.remove(projectAppQueryWrapper);
        createProjectApp(projectDTO.getPermissions(), project);
        // 检查权限组，移除不符合要求的项目
        permissionGroupHandler(project.getId());
        //记录日志
        projectLogRecord(account, LogOperationTypeEnum.UPDATE, "编辑项目" + "【" + project.getName() + "】", project);
        return ResultJson.success("更新成功");
    }

    /**
     * 移除在权限组里不合适的项目
     * @param projectId
     */
    private void permissionGroupHandler(Integer projectId){
        QueryWrapper<PermissionGroup> permissionGroupQueryWrapper = new QueryWrapper<>();
        permissionGroupQueryWrapper.like("project_ids", projectId);
        List<PermissionGroup> list = permissionGroupService.list(permissionGroupQueryWrapper);
        if(!CollectionUtils.isEmpty(list)){
            permissionGroupService.permissionGroupFilter(list.stream().map(i -> i.getId()).collect(Collectors.toList()));
        }
    }

    private static ResultJson paramCheck(ProjectDTO projectDTO) {
        if (null == projectDTO.getPermissions() || projectDTO.getPermissions().isEmpty()) {
            return ResultJson.fail("缺少权限信息");
        }
        if (com.xhwl.common.utils.StringUtils.isEmpty(projectDTO.getName()) || projectDTO.getName().length() > 32) {
            return ResultJson.fail("名称错误");
        }
//        if (null == projectDTO.getValidityDateStart() || null == projectDTO.getValidityDateEnd()) {
//            return ResultJson.fail("请填写有效期");
//        }
        if (null != projectDTO.getBuildingArea() && String.valueOf(projectDTO.getBuildingArea()).length() > 13) {
            return ResultJson.fail("建筑面积错误");
        }
        if (null != projectDTO.getOccupiedArea() && String.valueOf(projectDTO.getOccupiedArea()).length() > 13) {
            return ResultJson.fail("占地面积错误");
        }

        if (null != projectDTO.getProvinceId() && projectDTO.getProvinceId().toString().length() > 9) {
            return ResultJson.fail("省错误");
        }
        if (null != projectDTO.getCityId() && projectDTO.getCityId().toString().length() > 9) {
            return ResultJson.fail("市错误");
        }
        if (null != projectDTO.getDistrictId() && projectDTO.getDistrictId().toString().length() > 9) {
            return ResultJson.fail("区错误");
        }
        if (com.xhwl.common.utils.StringUtils.isNotEmpty(projectDTO.getAddress()) && projectDTO.getAddress().length() > 128) {
            return ResultJson.fail("地址输入错误");
        }
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(projectDTO.getContactPhone()) && !ValidatorUtil.isMobile(projectDTO.getContactPhone())) {
            return ResultJson.fail("手机号格式错误");
        }
        try {
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(projectDTO.getLatitude()) && (-90.0 > Double.valueOf(projectDTO.getLatitude()) || Double.valueOf(projectDTO.getLatitude()) > 90.0)) {
                return ResultJson.fail("维度格式错误");
            }
        } catch (Exception e) {
            log.error("维度格式错误, {}", e.getMessage());
            return ResultJson.fail("维度格式错误");
        }
        try {
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(projectDTO.getLongitude()) && (-180.0 > Double.valueOf(projectDTO.getLongitude()) || Double.valueOf(projectDTO.getLongitude()) > 180.0)) {
                return ResultJson.fail("经度格式错误");
            }
        } catch (Exception e) {
            log.error("经度格式错误", e.getMessage());
            return ResultJson.fail("经度格式错误");
        }
        return ResultJson.success();
    }

    @Override
    public ResultJson update(Project project) {
        if (null == project) {
            return ResultJson.fail("参数为空");
        }
        Project project1 = projectDao.selectById(project.getId());
        project1.setScreenUrl(project.getScreenUrl());
        projectDao.updateById(project1);
        return ResultJson.success("更新成功");
    }

    @Override
    public ProjectDTO detail(Integer id, Account account) {
        QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
        projectQueryWrapper.eq("id", id);
        projectQueryWrapper.eq("is_deleted", false);
        Project project = projectDao.selectOne(projectQueryWrapper);
        if (project == null) {
            return null;
        }
        QueryWrapper<ProjectPermission> projectPermissionQueryWrapper = new QueryWrapper<>();
        projectPermissionQueryWrapper.eq("project_id", id);
        List<ProjectPermission> projectPermissions = projectPermissionDao.selectList(projectPermissionQueryWrapper);

        ProjectDTO result = new ProjectDTO();
        if (!projectPermissions.isEmpty()) {
            result.setPermissions(projectPermissions.stream().map(p -> p.getPermissionId()).collect(Collectors.toList()));
        }
        BeanUtils.copyProperties(project, result);
        result.setOrgName(project.getName());
        return result;
    }

    @Override
    public Page<Project> listPage(ProjectQuery projectQuery, Account account, Page page) {

        QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
        // 处理请求参数
        if (null != account) {
            accountAuthFilter(projectQueryWrapper, account);
        }
        handleQueryParam(projectQueryWrapper, projectQuery);
        projectQueryWrapper.eq("is_deleted", false);
        Page page1 = projectDao.selectPage(page, projectQueryWrapper);
        convertView(page1.getRecords());
        return page1;
    }

    /**
     * 根据帐号过滤企业授权
     * @param projectQueryWrapper
     * @param account
     */
    private void accountAuthFilter(QueryWrapper<Project> projectQueryWrapper, Account account){
        List<Integer> enterpriseIds = accountService.getEnterpriseIds(account.getId());
        projectQueryWrapper.in("enterprise_id", enterpriseIds);
    }

    @Override
    public List<Project> list(ProjectQuery projectQuery, Account account) {
        QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
        // 处理请求参数
        if (null != account) {
            handlePermission(projectQueryWrapper, account);
        }
        handleQueryParam(projectQueryWrapper, projectQuery);
        projectQueryWrapper.eq("is_deleted", false);
        List<Project> projects = projectDao.selectList(projectQueryWrapper);
        return convertView(projects);
    }

    private List<Project> convertView(List<Project> projects) {
        Map<Integer, String> regionNameMap = new HashMap<>();
        List<Integer> regionSet = new ArrayList<>();
        if (!projects.isEmpty()) {
            projects.stream().forEach(p -> {
                if (null != p.getProvinceId()) {
                    regionSet.add(p.getProvinceId());
                }
                if (null != p.getCityId()) {
                    regionSet.add(p.getCityId());
                }
                if (null != p.getDistrictId()) {
                    regionSet.add(p.getDistrictId());
                }
            });
            List<Region> regions = regionService.findByIds(regionSet);
            regionNameMap = regions.stream().collect(Collectors.toMap(Region::getId, Region::getName));
        }
        Map<Integer, Integer> integerIntegerMap = projectCount(projects);
        for (Project p : projects) {
            if (null != p.getProvinceId()) {
                p.setProvinceName(regionNameMap.get(p.getProvinceId()));
            }
            if (null != p.getCityId()) {
                p.setCityName(regionNameMap.get(p.getCityId()));
            }
            if (null != p.getDistrictId()) {
                p.setDistrictName(regionNameMap.get(p.getDistrictId()));
            }
            //填充项目人数
            p.setStaffCount(integerIntegerMap.get(p.getId()));
        }
        return projects;
    }
    @Override
    public Map<Integer,Integer> projectCount(List<Project> projects) {
        if(CollectionUtils.isEmpty(projects)){
            return new HashMap<>();
        }
        List<Integer> collect = projects.stream().map(Project::getId).collect(Collectors.toList());
        //查询关联企业
        QueryWrapper<EnterpriseProject> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("enterprise_id","project_id");
        queryWrapper.in("project_id",collect);
        List<EnterpriseProject> list = enterpriseProjectDao.selectList(queryWrapper);
        if(CollectionUtils.isEmpty(list)){
            return new HashMap<>();
        }
        Map<Integer,List<Integer>> projectEntMap = list.stream().collect(Collectors.groupingBy(EnterpriseProject::getProjectId,Collectors.mapping(i -> i.getEnterpriseId(), Collectors.toList())));
        List<Integer> entIds = list.stream().map(EnterpriseProject::getEnterpriseId).collect(Collectors.toList());
        Map<Integer,Integer> entMap = enterpriseService.getStaffCount(entIds);
        Map<Integer,Integer> projectMap = new HashMap<>();
        for (Map.Entry<Integer,List<Integer>> integerListEntry : projectEntMap.entrySet()){
            List<Integer> entId = integerListEntry.getValue();
            Map<Integer,Integer> entStaffCountMap = entMap.entrySet().stream().filter(i -> entId.contains(i.getKey())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
            projectMap.put(integerListEntry.getKey(),entStaffCountMap.values().stream().mapToInt(Integer::intValue).sum());
        }
        return projectMap;
    }

    @Override
    public Project getOne(ProjectQuery projectQuery, Account account) {
        QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
        // 处理请求参数
        if (null != account) {
            accountAuthFilter(projectQueryWrapper, account);
        }
        handleQueryParam(projectQueryWrapper, projectQuery);
        projectQueryWrapper.eq("is_deleted", false);
        Project project = null;
        try {
            project = projectDao.selectOne(projectQueryWrapper);

        } catch (Exception e) {
            log.error("项目 {} 查询失败， 原因 {}", projectQuery, e.getMessage());
        }
        return project;
    }

    @Override
    public List<Project> getProjectByAccount(Integer enterpriseId, Integer accountId){
        QueryWrapper<PermissionGroup> permissionGroupQueryWrapper = new QueryWrapper<>();
        permissionGroupQueryWrapper.eq("account_id", accountId);
        permissionGroupQueryWrapper.eq("enterprise_id", enterpriseId);
        permissionGroupQueryWrapper.orderByAsc("created_at");
        List<PermissionGroup> list = permissionGroupService.list(permissionGroupQueryWrapper);
        if (null != list){
            PermissionGroup permissionGroup = list.get(0);
            List<Integer> collect = Arrays.asList(permissionGroup.getProjectIds().split(",")).stream().map(i -> Integer.valueOf(i)).collect(Collectors.toList());
            List<Project> projects = projectDao.selectBatchIds(collect);
            return projects;
        }
        return null;
    }

    public void handleQueryParam(QueryWrapper<Project> projectQueryWrapper, ProjectQuery projectQuery) {
        if (null != projectQuery) {
            if (!StringUtils.isEmpty(projectQuery.getLikeProjectName())){
                projectQueryWrapper.like("name",projectQuery.getLikeProjectName());
            }
            if (null != projectQuery.excludeId) {
                projectQueryWrapper.ne("id", projectQuery.excludeId);
            }
            if (null != projectQuery.id) {
                projectQueryWrapper.eq("id", projectQuery.id);
            }
            if (!CollectionUtils.isEmpty(projectQuery.ids)) {
                projectQueryWrapper.in("id", projectQuery.ids);
            }
            if (null != projectQuery.enterpriseId) {
                projectQueryWrapper.eq("enterprise_id", projectQuery.enterpriseId);
            }
            if (!StringUtils.isEmpty(projectQuery.code)) {
                projectQueryWrapper.eq("code", projectQuery.code);
            }

            if (null != projectQuery.organizationId) {
                wrapperProjectId(projectQueryWrapper, projectQuery);
            }
            if (null != projectQuery.organizationIds && !projectQuery.organizationIds.isEmpty()) {
                wrapperProjectId(projectQueryWrapper, projectQuery);
            }
            if (null != projectQuery.name) {
                projectQueryWrapper.eq("name", projectQuery.name);
            }
            if (!CollectionUtils.isEmpty(projectQuery.enterpriseIds)) {
                projectQueryWrapper.in("enterprise_id", projectQuery.enterpriseIds);
            }
            if (null != projectQuery.industryId) {
                projectQueryWrapper.eq("industry_id", projectQuery.industryId);
            }
            if (!StringUtils.isEmpty(projectQuery.keywords)) {
                projectQueryWrapper.and(wrapper -> wrapper.like("name", projectQuery.keywords).or().like("code", projectQuery.keywords));
            }
            if (CollectionUtils.isNotEmpty(projectQuery.getProjectNames())) {
                projectQueryWrapper.in("name", projectQuery.getProjectNames());
            }
            if (CollectionUtils.isNotEmpty(projectQuery.getCodes())) {
                projectQueryWrapper.in("code", projectQuery.getCodes());
            }
            if (CollectionUtils.isNotEmpty(projectQuery.getCityIds())) {
                projectQueryWrapper.in("city_id", projectQuery.getCityIds());
            }
            if (CollectionUtils.isNotEmpty(projectQuery.getBelongToOrg())){
                List<Organization> organizationList = organizationService.child(new OrganizationQuery().withIds(projectQuery.getBelongToOrg()));
                projectQueryWrapper.in("belong_to_org",organizationList.stream().map(Organization::getId).collect(Collectors.toList()));
            }
        }
    }

    private void wrapperProjectId(QueryWrapper<Project> projectQueryWrapper, ProjectQuery projectQuery) {
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.select("id", "type", "level", "parent_id", "enterprise_id", "project_id");
        if (null == projectQuery.organizationIds || projectQuery.organizationIds.isEmpty()) {
            return;
        }
        organizationQueryWrapper.in("id", projectQuery.organizationIds);
        List<Organization> organizations = organizationDao.selectList(organizationQueryWrapper);
        if (!organizations.isEmpty()) {
            // 判断是否是org类型 如果是需要查询下级所有项目id 满足根据组织查询项目的条件
            List<Organization> collect = organizations.stream().filter(o -> OrganizationTypeEnum.ORG.id.intValue() == o.getType() || OrganizationTypeEnum.PROJECT.id.intValue() == o.getType()).collect(Collectors.toList());
            List<Organization> enterprise = organizations.stream().filter(o -> OrganizationTypeEnum.ENTERPRISE.id.intValue() == o.getType()).collect(Collectors.toList());
            if (!collect.isEmpty()) {
                if (projectQuery.ids != null) {
                    projectQuery.ids.addAll(findChildProjectId(collect));
                } else {
                    Collection<Integer> childProjectId = findChildProjectId(collect);
                    if (!childProjectId.isEmpty()) {
                        projectQueryWrapper.in("id", childProjectId);
                    } else {
                        projectQueryWrapper.eq("id", -1);
                    }
                }
            } else if (!enterprise.isEmpty()) {
                projectQueryWrapper.in("enterprise_id", enterprise.stream().map(e -> e.getEnterpriseId()).collect(Collectors.toList()));
            } else {
                projectQueryWrapper.eq("id", -1);
            }
        }
    }

    /**
     * 查询组织下级项目id
     *
     * @param defaultOrg
     * @return
     */
    public Collection<Integer> findChildProjectId(List<Organization> defaultOrg) {
        if (defaultOrg.isEmpty()) {
            return Collections.emptyList();
        }
        List<Integer> collect = defaultOrg.stream().map(ent -> ent.getEnterpriseId()).collect(Collectors.toList());
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.in("enterprise_id", collect);
        List<Organization> allEnt = organizationDao.selectList(organizationQueryWrapper);
        Set<Integer> result = new HashSet<>();
        for (Organization organization : defaultOrg) {
            if (OrganizationTypeEnum.PROJECT.id.intValue() == organization.getType()) {
                result.add(organization.getProjectId());
                continue;
            }
            List<Organization> currents = Arrays.asList(organization);
            while (true) {
                List<Integer> ids = currents.stream().map(c -> c.getId()).collect(Collectors.toList());
                List<Organization> collect1 = allEnt.stream().filter(a -> ids.contains(a.getParentId())).collect(Collectors.toList());

                if (collect1.isEmpty()) {
                    // 没有下级
                    break;
                }
                currents = collect1;
                // 默认找到parentId ！= null 的就表示找到项目那一层级了
                List<Organization> collect3 = currents.stream().filter(c -> OrganizationTypeEnum.PROJECT.id.intValue() == c.getType()).collect(Collectors.toList());
                if (!collect3.isEmpty()) {
                    List<Integer> collect2 = collect3.stream().filter(c -> c.getProjectId() != null).map(c -> c.getProjectId()).distinct().collect(Collectors.toList());
                    result.addAll(collect2);
                }
            }
        }
        return result;
    }

    @Override
    public Project findById(Integer projectId) {
        QueryWrapper<Project> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", projectId).eq("is_deleted", false);
        List<Project> projects = projectDao.selectList(queryWrapper);
        if (projects.isEmpty()) {
            return null;
        }
        return projects.get(0);
    }

    @Override
    public ResultJson nameCheck(Integer projectId, String name, Integer enterpriseId) {
        // 名称校验
        QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
        if (null != projectId) {
            projectQueryWrapper.ne("id", projectId);
        }
        if (null == enterpriseId) {
            log.error("名称校验缺少企业id参数");
            return ResultJson.fail("参数错误");
        }
        projectQueryWrapper.eq("enterprise_id", enterpriseId);
        projectQueryWrapper.eq("name", name);
        projectQueryWrapper.eq("is_deleted", false);
        List<Project> projects1 = projectDao.selectList(projectQueryWrapper);
        if (!projects1.isEmpty()) {
            return ResultJson.fail("名称重复");
        } else {
            return ResultJson.success("通过");
        }
    }

    @Override
    public ResultJson setBan(Account account, Integer id, Boolean isBan) {
        Project project = this.getOne(new ProjectQuery(id), account);
        if (null == project) {
            return ResultJson.fail("项目不存在");
        }
        project.setStatus(isBan ? (short) 0 : (short) 1);
        projectDao.updateById(project);

        StringBuilder sbd = new StringBuilder();
        sbd.append(isBan ? "禁用" : "启用").append("项目管理：").append(project.getName()).append("项目");

        //记录日志
        projectLogRecord(account, isBan ? LogOperationTypeEnum.BAN : LogOperationTypeEnum.ACTIVE, sbd.toString(), project);
        return ResultJson.success();
    }

    @Override
    public ResultJson getProjectAreaCount(ProjectQuery projectQuery) {
        if (null == projectQuery.getProjectId()) {
            return ResultJson.fail("参数有误");
        }
        QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
        projectQueryWrapper.eq("is_deleted", 0);
        projectQueryWrapper.eq("id", projectQuery.getProjectId());
        Project project = projectDao.selectOne(projectQueryWrapper);
        if (null == project) {
            return ResultJson.fail("该项目不存在");
        }
        if (project.getStatus() == 0) {
            return ResultJson.fail("该项目已被禁用");
        }
        HashMap<String, Double> hashMap = new HashMap<>();
        hashMap.put("buildingArea", project.getBuildingArea());
        hashMap.put("occupiedArea", project.getOccupiedArea());
        return ResultJson.success(hashMap);
    }

    @Override
    public Map getTotalProjectAreaCount() {
        //获取所有项目
        QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
        projectQueryWrapper.eq("is_deleted", 0).eq("status", 1);
        List<Project> projects = projectDao.selectList(projectQueryWrapper);
        double totalBuildingArea = projects.stream().filter(p -> !StringUtils.isEmpty(p.getBuildingArea())).mapToDouble(Project::getBuildingArea).sum();
        double totaloccupiedArea = projects.stream().filter(p -> !StringUtils.isEmpty(p.getOccupiedArea())).mapToDouble(Project::getOccupiedArea).sum();
        HashMap<String, Double> returnMap = new HashMap<>();
        returnMap.put("totalBuildingArea", totalBuildingArea);
        returnMap.put("totaloccupiedArea", totaloccupiedArea);
        return returnMap;
    }

    @Override
    public Integer getBuildingCount(ProjectQuery projectQuery){
        if (null == projectQuery.getProjectId()){
            throw new BusinessException("参数有误");
        }
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.eq("type", OrganizationTypeEnum.BUILDING.id);
        organizationQueryWrapper.eq("project_id", projectQuery.getProjectId());
        return organizationService.count(organizationQueryWrapper);
    }

    @Override
    public List<Project> getProjectSupportTouristList(Short industry) {
        List<Role> roleList = roleService.getTouristRoleByIndustryId(industry);
        if (CollectionUtils.isEmpty(roleList)) {
            return Collections.emptyList();
        }
        //通过游客角色配置的权限，查找需要这些角色权限的项目
        List<Integer> ids = roleList.stream().map(role -> role.getId()).collect(Collectors.toList());
        List<Integer> permissionIds = rolePermissionService.getPermissionIdByRoleId(ids);
        if(CollectionUtils.isEmpty(permissionIds)){
            return Collections.emptyList();
        }
        List<Integer> projectIds = projectPermissionService.getProjectIdByPermissionId(permissionIds);
        if(CollectionUtils.isEmpty(projectIds)){
            return Collections.emptyList();
        }
        List<Project> projects = getBaseMapper().selectBatchIds(projectIds);
        return projects;
    }

    @Override
    public List<Project> findByEntId(Integer enterpriseId,String keywords) {
        Enterprise enterprise = enterpriseDao.selectById(enterpriseId);
        if(enterprise == null){
            return new ArrayList<>();
        }
        if(enterprise.getType().contains("1")){
            //运营商企业
            QueryWrapper<Project> queryWrapper = new QueryWrapper();
            queryWrapper.eq("enterprise_id",enterpriseId);
            if (null !=keywords){
                queryWrapper.like("name",keywords);
            }
            queryWrapper.eq("is_deleted",0);
            List<Project> projects = projectDao.selectList(queryWrapper);
            for (Project project : projects) {
                Scene scene = sceneService.getById(project.getSceneId());
                if (null != scene){
                    project.setSceneName(scene.getName());
                }
            }
            return projects;
        }else{
            //入驻企业
            // 查询入驻企业的授权项目
            QueryWrapper<EnterpriseProject> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("enterprise_id", enterpriseId);
            List<EnterpriseProject> list = enterpriseProjectDao.selectList(queryWrapper);
            if(CollectionUtils.isNotEmpty(list)){
                List<Integer> projectIds = list.stream().map(i -> i.getProjectId()).distinct().collect(Collectors.toList());
                QueryWrapper<Project> projectQueryWrapper = new QueryWrapper();
                projectQueryWrapper.in("id",projectIds);
                if (null !=keywords){
                    projectQueryWrapper.like("name",keywords);
                }
                List<Project> projects = projectDao.selectList(projectQueryWrapper);
                for (Project project : projects) {
                    Scene scene = sceneService.getById(project.getSceneId());
                    if (null != scene){
                        project.setSceneName(scene.getName());
                    }
                }
                return projects;
            }
        }
        return new ArrayList<>();
    }

    /**
     * 创建项目管理员角色
     *
     * @param project
     * @param permissionIdList
     * @return
     */
    private ResultJson<Integer> createManagerRole(Project project, List<Integer> permissionIdList) {

        // 创建项目管理员需要过滤掉 新增企业，修改企业，
        QueryWrapper<Permission> permissionQueryWrapper = new QueryWrapper<>();
        permissionQueryWrapper.select("id");
        permissionQueryWrapper.in("code", EXCLUDE_PROJECT_PERMISSION);
        List<Permission> permissions = permissionDao.selectList(permissionQueryWrapper);
        if (!permissions.isEmpty()) {
            List<Integer> exIds = permissions.stream().map(p -> p.getId()).collect(Collectors.toList());
            permissionIdList.removeAll(exIds);
        }

        RoleGrantDTO roleGrantDTO = new RoleGrantDTO();
        roleGrantDTO.setIndustryId(project.getIndustryId());
        roleGrantDTO.setEnterpriseId(project.getEnterpriseId());
        roleGrantDTO.setProjectId(project.getId());
        roleGrantDTO.setName(RoleTypeEnum.PRO_MANAGER.name);
        roleGrantDTO.setGrade(BusinessType.PROJECT.code);
        roleGrantDTO.setType(RoleTypeEnum.MANAGER.code);
        roleGrantDTO.setIsInitialized(true);
        roleGrantDTO.setLevel(1);
        roleGrantDTO.setSortNum(1);
        roleGrantDTO.setParentId(0);
        roleGrantDTO.setPermissionIds(permissionIdList);
        roleGrantDTO.setOrganizationId(project.getOrganizationId());
        return roleService.createRole(roleGrantDTO);
    }

    /**
     * 保存项目与权限关系
     * 默认添加菜单下对应按钮权限
     *
     * @param projectId
     * @param permissionIdList
     */
    private List<Integer> savePermissions(Integer projectId, List<Integer> permissionIdList) {
        List<Integer> buttonPermissionIdList = permissionService.findButtonIdByMenuId(permissionIdList);
        if (!CollectionUtils.isEmpty(buttonPermissionIdList)) {
            permissionIdList.addAll(buttonPermissionIdList);
        }
        projectPermissionService.save(projectId, permissionIdList.stream().distinct().collect(Collectors.toList()));
        return permissionIdList;
    }

    /**
     * 删除关联关系
     *
     * @param projectId
     */
    private void deleteRelation(Integer projectId) {
        projectPermissionService.deleteProjectPermission(Arrays.asList(projectId), null);
    }

    /**
     * 查询项目管理员角色id
     *
     * @param projectId
     * @return
     */
    private List<Role> queryManagerRoleId(Integer projectId) {
        RoleQuery roleQuery = new RoleQuery();
        roleQuery.setGrade(BusinessType.PROJECT.code);
        roleQuery.setType(RoleTypeEnum.MANAGER.code);
        roleQuery.setProjectIdList(Arrays.asList(projectId));
        return roleService.getRoleList(null, roleQuery);
    }

    /**
     * 处理请求参数
     *
     * @param projectQuery
     * @param account
     */
    private void handlePermission(QueryWrapper<Project> projectQuery, Account account) {
        if (null == account) {
            return;
        }
        RoleTypeDTO roleTypeDTO = roleService.getAccountRoleType(account.getId());
        // 账号管理项目
//        projectQuery.eq("industry_id", account.getIndustryId());
        if (roleService.isSuperManager(account.getId())) {
            // 超级管理员能查询当前业态环境下的所有组织
        } else if (roleService.isOperationalManager(account.getId())) {
            // 运维角色暂未规划
        } else if (roleService.isEntManager(account.getId())) {
            QueryWrapper<AccountOrganization> accountOrganizationQueryWrapper = new QueryWrapper<>();
            accountOrganizationQueryWrapper.eq("account_id", account.getId());
//            accountOrganizationQueryWrapper.eq("type", 1);
            List<AccountOrganization> accountOrganizations = accountOrganizationDao.selectList(accountOrganizationQueryWrapper);
            if (accountOrganizations.isEmpty()) {
                log.error("该帐号 {}  {} 暂未关联企业信息", account.getId(), account.getLoginName());
                throw new BusinessException("该帐号暂未关联企业信息");
            }
            // 普通帐号没有多企业
            projectQuery.in("enterprise_id", accountOrganizations.stream().map(i -> i.getEnterpriseId()).collect(Collectors.toList()));
        } else if (RoleTypeEnum.TOURIST.equals(roleTypeDTO.getRoleTypeEnum())){
            projectQuery.select("id","name");
        }
        else{
                // 普通帐号 能查询到的project
                QueryWrapper<AccountProject> accountProjectQueryWrapper = new QueryWrapper<>();
                accountProjectQueryWrapper.eq("account_id", account.getId());
                List<AccountProject> accountProjects = accountProjectDao.selectList(accountProjectQueryWrapper);
                if (accountProjects.isEmpty()) {
                    projectQuery.eq("id", -1);
                } else {
                    projectQuery.in("id", accountProjects.stream().map(a -> a.getProjectId()).collect(Collectors.toList()));
                }
            }
    }


    /**
     * 校验规则：
     * 1、code全局唯一
     * 2、name同一个企业下唯一
     *
     * @param project
     */
    private void saveCheck(Project project) {
        QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
        // 编码校验
        projectQueryWrapper.eq("code", project.getCode());
        if (null != project.getId()) {
            projectQueryWrapper.ne("id", project.getId());
        }
        projectQueryWrapper.select("id");
        List<Project> projects = projectDao.selectList(projectQueryWrapper);
        if (!projects.isEmpty()) {
            log.error("编码重复");
            throw new BusinessException("编码重复");
        }
        ResultJson resultJson = nameCheck(project.getId(), project.getName(), project.getEnterpriseId());
        if (!resultJson.getState()) {
            log.error("名称重复");
            throw new BusinessException("名称重复");
        }
    }

    public void projectLogRecord(Account operateAccount, LogOperationTypeEnum logOperationTypeEnum, String operateContent, Project project) {
        OperateLog operateLog = new OperateLog();
        operateLog.setMenu(ModuleTypeEnum.PROJECT_MANAGE.getName());
        operateLog.setOperateType(logOperationTypeEnum.getType());
        operateLog.setOperateContent(operateContent);
        operateLog.setEnterpriseId(project.getEnterpriseId());
        operateLog.setProjectId(project.getId());
        operateLog.setProjectName(project.getName());
        operateLog.setIp(ThreadLocalUtil.getIp());
        operateLog.setIndustryId(ThreadLocalUtil.getIndustryId());
        if (null == operateAccount) {
            operateAccount = ThreadLocalUtil.getAccount();
        }
        if (null != operateAccount) {
            operateLog.setIndustryId(operateAccount.getIndustryId());
            operateLog.setAccountId(operateAccount.getId());
            operateLog.setLoginName(operateAccount.getLoginName());
            operateLog.setName(operateAccount.getName());
            //填充企业ids+项目ids
            List<Enterprise> enterprises = enterpriseService.list(null,operateAccount);
            if (!org.springframework.util.CollectionUtils.isEmpty(enterprises)){
                operateLog.setEnterpriseIds(enterprises.stream().map(Enterprise::getId).collect(Collectors.toList()));
            }
            List<AccountDetailDTO> projectInfoList = accountService.getAccountProjectInfoByIdList(Collections.singletonList(operateAccount.getId()));
            operateLog.setProjectIds(projectInfoList.stream().map(AccountDetailDTO::getProjectId).collect(Collectors.toList()));
            if (!org.springframework.util.CollectionUtils.isEmpty(projectInfoList)){
                operateLog.setProjectIds(projectInfoList.stream().map(AccountDetailDTO::getProjectId).collect(Collectors.toList()));
            }
        }
        logTemplate.addOperateLog(operateLog);

    }
}